home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / pascal / clp.exe / CLPARSER.DOC < prev    next >
Encoding:
Text File  |  1992-09-07  |  30.8 KB  |  795 lines

  1.  
  2.   ___________________________________________________________________________
  3.  
  4.   CLPARSER.TPU                           Copyright (c) 1989-92 Greg Truesdell
  5.   Version 3.2                                      a Turbo Pascal Object Unit
  6.   ___________________________________________________________________________
  7.  
  8.  
  9.   ABOUT THE AUTHOR___________________________________________________________
  10.  
  11.   The author is an Information Technology Specialist at the Education
  12.   Development Centre in Burnaby, BC, Canada.  The EDC is an industrial
  13.   training and development facility which provides state-of-the-art CBT and
  14.   instructor led courses to corporations and governments throught-out Canada,
  15.   The United States, Europe, Middle East and Far East. As a member of the
  16.   BC Tel Group of Companies, the EDC specializes in Telecommunications,
  17.   Mainframe Computer, Personal Computer, Management, Engineering and Sales
  18.   training as well as Educational Development Resources.
  19.  
  20.   The author was trained as an Aviation Electronics Tech. in the US Navy and
  21.   joined the British Columbia Telephone Co. in 1974.  He held positions in
  22.   Test Desk, Teletype/Data (computer maintenance) and Instructor of computer
  23.   technology courses.
  24.  
  25.   The author is currently responsible for the design, implementation and
  26.   support of Database and Office Automation Systems and products used by the
  27.   EDC, and has co-produced their multi-user time tracking and shared project
  28.   reporting system, the automated billing system, the VAX PCSA-based Office
  29.   Automation multi-user menuing system, the information and report
  30.   distribution system and the student registration and confirmation system.
  31.  
  32.   He is a member of a four person team responsible for all computer-based
  33.   information services required by more than 150 networked PC users as well
  34.   as over 100 mainframe SNA and direct access ports.  Languages of choice
  35.   are Clipper, dBase, Vax C, Turbo C and MS C, Turbo C++, Turbo Pascal and
  36.   Assembler.
  37.  
  38.   He lives with his wife of 20 years, Julia, and their two sons, Joe (18)
  39.   and Duncan (17).  Many thanks to Julia for her MUCH patience!
  40.  
  41.  
  42.   INTRODUCTION_______________________________________________________________
  43.  
  44.   CLParser.TPU is a Command Line Parser.  It provides the programmer with
  45.   several pre-defined objects for dealing with command line options and
  46.   switches.  The unit also provides parsing for wildcard filenames, all
  47.   environment variables and simple text parameter files.
  48.  
  49.   The unit provides methods which manipulate lists of items.  The primary
  50.   object is CLPLIST.  The following is the type definition for CLPLIST:
  51.  
  52.     ItemRecordP = ^ItemRecord;
  53.     ItemRecord = Record
  54.  
  55.         Item        :^String;       { parsed item String }
  56.         ItemLen     : Byte;         { length + 2 of item String }
  57.         Posn        : LongInt;      { position }
  58. |       Cargo       : Pointer;      { data record pointer }
  59. |       CargoLen    : LongInt;      { size of data record pointer }
  60.         NextItem    : ItemRecordP;  { pointer to the next node in list }
  61.         PrevItem    : ItemRecordP;  { pointer to previous node in list }
  62.  
  63.     end;
  64.  
  65.     { list is the data structure }
  66.     pClpList = ^clpList;
  67.     clpList = object
  68.  
  69.         firstitem   : ItemRecordP;  { pointer to first record in list }
  70.         currentitem : ItemRecordP;  { pointer to current record in list }
  71.         lastitem    : ItemRecordP;  { pointer to last record in list}
  72.         items       : Word;         { number of items in the list }
  73.         index       : Word;         { current item number }
  74.  
  75.         Constructor Init;
  76.         Destructor  Done;
  77.         Function    Add( add_item: String; locn: LongInt ): Boolean;
  78. |       Function    AddCargo( Add_Item: String; Locn: LongInt;
  79. |           pCargo : Pointer; CargoSize: Word ) : Boolean;
  80.         Function    Next:                                   String;
  81. |       Function    NextCargo( var pCargo : Pointer; var CargoSize : LongInt ) : String;
  82.         Function    Prev:                                   String;
  83. |       Function    PrevCargo( var pCargo : Pointer; var CargoSize : LongInt ) : String;
  84.         Function    Count:                                  Word;
  85.         Function    Position:                               LongInt;
  86.         Procedure   Reset;
  87.     end;
  88.  
  89.     { help is a list of help lines }
  90.     pHelp = ^Help;
  91.     Help = object(clpList)
  92.         ScreenLines : Byte;
  93.         LineCount   : Byte;
  94.  
  95.         Constructor Init( nLines : Byte );
  96.         Function    ReadFile( filename : String ) : Boolean;
  97.         Procedure   Display;
  98.     end;
  99.  
  100.     { argument is a list of arguments }
  101.  
  102.     pArgument = ^Argument;
  103.     Argument = object(clpList)
  104.  
  105.         more    : Boolean;
  106.  
  107.         Constructor Init( LegalChars: CharSet );
  108.         Function    Find( target : String ): String;
  109.         Function    Overflow: Boolean;
  110.  
  111.     end;
  112.  
  113.     { Environ is a list of environment variables }
  114.  
  115.     pEnviron = ^Environ;
  116.     Environ = object(Argument)
  117.  
  118.         Constructor Init;
  119.  
  120.     end;
  121.  
  122.     { wild is a special list of filenames }
  123.  
  124.     { ======================================================== }
  125.     {                                                          }
  126.     { NOTE:  The pWild object calls the AddCargo method using  }
  127.     {        the search record returned by the FindFirst() and }
  128.     {        FindNext() DOS unit procedures.                   }
  129.     {                                                          }
  130.     { ======================================================== }
  131.  
  132.     pWild = ^Wild;
  133.     Wild = object(argument)
  134.  
  135.         Constructor Init( filemask: String; attributes: Word );
  136.  
  137.     end;
  138.  
  139.     { pfile is a special list of parameter file entries }
  140.     pPFile = ^PFile;
  141.     PFile = object(argument)
  142.  
  143.         Constructor Init( filename: String; comment: CharSet );
  144.  
  145.     end;
  146.  
  147.  
  148.   The CLPLIST object can be used to maintain any kind of sequential list of
  149.   strings.  Each item in the list is a pointer to a variable length string
  150.   and a location word.  The location word was primarily provided to register
  151.   where, on the command line, the item was found.  It may also be used to
  152.   mark entries in the list for other reasons.
  153.  
  154.   Version 2.x was restricted to 1024 entries in any one of the objects.  In
  155.   version 3.x, no such restriction applies.  The only restriction is the
  156.   amount of available heap memory.
  157.  
  158.   Since all other objects in this unit are based on this object, and because
  159.   none of these objects add any data instances of their own, the above
  160.   paragraph is true for them also.
  161.  
  162.  
  163.   The following is a list of all objects defined in CLPARSER.TPU:
  164.  
  165.       name(type)  unique methods
  166.       ----------- --------------------------------------------------------
  167.       CLPLIST     Init      : Clear list to initial values (nil).
  168.       (object)    Done      : Erase and reclaim memory used by the list.
  169.                   Add       : Add an item to the list.
  170. |                 AddCargo  : Add an item to the list with cargo.
  171.                   Next      : Step forward and get next item.
  172. |                 NextCargo : Get next item with cargo.
  173.                   Prev      : Step backward and get previous item.
  174. |                 PrevCargo : Get previous item with cargo.
  175.                   Count     : Return the number of items in the list.
  176.                   Position  : Return line position of this item.
  177.                   Reset     : Reset the item pointer to the beginning.
  178.       ----------- --------------------------------------------------------
  179.       ARGUMENT    Init      : Fill array with valid arguments.
  180.       (clplist)   Find      : Locate a specific argument.
  181.                   Overflow  : Returns TRUE if there were more arguments
  182.                               than could fit in memory.
  183.       ----------- --------------------------------------------------------
  184.       WILD        Init      : Fill the array with filenames that match the
  185.       (argument)              filename mask.
  186.       ----------- --------------------------------------------------------
  187.       ENVIRON     Init      : Fill the array with all environment
  188.       (argument)              variables.
  189.       ----------- --------------------------------------------------------
  190.       PFILE       Init      : Fill the array with all parameters from a
  191.       (argument)              text parameter file.
  192.       ----------- --------------------------------------------------------
  193.  
  194.   The CLPLIST object is the primary object. The ARGUMENT object inherits all
  195.   of CLPLIST's methods except "Init", and adds two new methods; "Find" and
  196.   "Overflow".  The remaining objects (WILD, ENVIRON and PFILE) all inherit
  197.   the methods from CLPLIST and ARGUMENT except "Init".  Once you understand
  198.   how to use CLPLIST and ARGUMENT, then you need only examine the difference
  199.   in the "Init" methods for the remaining objects.
  200.  
  201.  
  202.  
  203.   HOW TO USE CLPARSER.TPU____________________________________________________
  204.  
  205.   To use CLPARSER, simply include the USES CLPARSER statement in your program
  206.   header.  You must also ensure that CLPARSER.TPU is placed in the directory
  207. | where you keep your units; usually \TP\UNITS.  CLPARSER no longer automa-
  208. | tically parses the commandline for you when the program executes.  You will
  209. | need to instantiate the object directly in your code.  For example:
  210. |
  211. |   Automatically instantiated:
  212. |
  213. |       Var
  214. |           Parse_Argument :  Argument; {List of arguments from commandline}
  215. |           Parse_Switch   :  Argument; {List of switches from commandline}
  216. |       Begin
  217. |           Parse_Argument.Init(NormalChars-Switches);
  218. |           Parse_Switch.Init(Switches);
  219. |           if Parse_Switch.Count > 0 then ...
  220. |           ....
  221. |           ....
  222. |           Parse_Argument.Done;
  223. |           Parse_Switch.Done;
  224. |       End.
  225. |
  226. |   Dynamically instantiated:
  227. |
  228. |       Var
  229. |           pArg, pSw : pArgument;
  230. |       Begin
  231. |           pArg := New( pArgument, Init( NormalChars-Switches ));
  232. |           pSw := New( pArgument, Init( Switches ));
  233. |           if pSw^.Count > 0 then ...
  234. |           ....
  235. |           ....
  236. |           Dispose( pSw, Done );
  237. |           Dispose( pArg, Done );
  238. |       End.
  239. |
  240. |   Other available objects are :
  241. |
  242. |         Wild       (pWild) : list of filenames and search records
  243. |         Environ (pEnviron) : list of environment variables
  244. |         PFile     (pPFile) : list of parameter file items
  245. |         Help       (pHelp) : lines of help text.
  246.  
  247.   Data Structure Access Methods
  248.  
  249.   In the introduction section you will find a list of objects and unique
  250.   methods associated with them.  From that list you can see the data struct-
  251.   ure access methods available for the ARGUMENT and SWITCH objects.  Let's
  252.   first examine the automatically initialized data structures.
  253.  
  254.  
  255.   Examine this program:
  256.  
  257.      program CLParser_Sample;
  258.  
  259.      uses CLParser;
  260.  
  261.      var
  262.         I : Integer;
  263. |       pArg, pSw : pArgument;
  264.  
  265.      begin
  266. |       pArg := New( pArgument, Init(NormalChars-Switches) );
  267. |       pSw  := New( pArgument, Init(Switches) );
  268. |
  269. |       if pArg^.Count > 0 then
  270.         begin
  271. |           Write('There are ',pArg^.Count );
  272.             WriteLn(' arguments on the command line.');
  273.  
  274. |           for I := 1 to pArg^.Count do
  275. |               WriteLn( pArg^.Next );
  276.  
  277.             WriteLn('End of Arguments');
  278.         end
  279.         else WriteLn('There were NO arguments on the command line.');
  280.  
  281.         WriteLn;
  282.  
  283. |       if pSw^.Count > 0 then
  284.         begin
  285. |           Write('There are ',pSw^.Count );
  286.             WriteLn(' arguments on the command line.');
  287.  
  288. |           for I := 1 to pSw^.Count do
  289. |               WriteLn( pSw^.Next );
  290.  
  291.             WriteLn('End of Switches');
  292.         end
  293.         else WriteLn('There were NO switches on the command line.');
  294.  
  295. |       Dispose( pSw, Done );
  296. |       Dispose( pArg, Done );
  297.     end.
  298.  
  299.   When this program is compiled and executed, the two data structures are
  300. | initially filled with items.  The unit determines which items on the
  301.   command line are switches or arguments by checking the first character
  302.   of the item.
  303.  
  304.        o    Switches are items that begin with '/', '-' or '+'.
  305.  
  306.        o    Arguments are items that begin with any normal character.
  307.             Normal characters are [#32..#127].
  308.  
  309.  
  310. | The program executes:
  311. |
  312. |       pArg := New( pArgument, Init(NormalChars-Switches) );
  313. |
  314. |               and
  315. |
  316. |       pSw  := New( pArgument, Init(Switches) );
  317.  
  318.   when the program starts.  The initialization method is passed the set of
  319.   valid first characters for each data structure.  In the example program
  320.   above, the arguments listed would be any that do not start with a switch
  321.   character but DO start with a normal character.  All other items on the
  322.   commandline are IGNORED!
  323.  
  324.   Assume you have compiled the example program as SAMPLE.EXE and typed:
  325.  
  326.         SAMPLE ONE TWO /A THREE -B +C FOUR
  327.  
  328.   The program would display:
  329.  
  330.         There are 4 arguments on the command line.
  331.         ONE
  332.         TWO
  333.         THREE
  334.         FOUR
  335.  
  336.         There are 3 switches on the command line.
  337.         /A
  338.         -B
  339.         +C
  340.  
  341.   The methods used in the example are COUNT and NEXT.  COUNT returns the
  342.   number of items in the list. Parse_Argument.COUNT returns the number of
  343.   arguments parsed from the command line.  NEXT returns the next item in the
  344.   list; Parse_Argument.NEXT returns the next argument from the list.
  345.  
  346.         examples:
  347.  
  348. |               Current_Position := pSw^.Position;
  349. |               Next_Argument := pArg^.Next;
  350. |               pSw^.Reset;
  351. |               If pSw^.Add('SETUP.DAT',0) then .....
  352.  
  353.  
  354.   Here is a list of available UNIQUE methods:
  355.  
  356. |      (Argument).Init( LegalChars: CharSet )
  357. |      (Wild).Init( FileMask: string; Attributes: word )
  358. |      (Environ).Init
  359. |      (PFile).Init( Filename: string; Comment: CharSet )
  360.  
  361.  
  362.  
  363.   REFERENCE__________________________________________________________________
  364.  
  365.  
  366.   Method:       ADD( add_item: string; locn: byte ): BOOLEAN
  367.  
  368.   Type:         Function
  369.  
  370.   Definition:   The ADD method is used to add an item to the end of the
  371.                 list. If the ADD is successful, the function returns TRUE.
  372.                 Failure to ADD occurs only if there is not enough memory
  373.                 on the heap for a new item.
  374.  
  375.                 The LOCN parameter is normally used with Parse_Argument and
  376.                 Parse_Switch to indicate where on the command line an item
  377.                 was found. It can be used by the programmer to supply a
  378.                 unique or special code to an item.
  379.  
  380.  
  381.   Usage:        If not pWild^.ADD('C:\COMMAND.COM',0)
  382.                 Then WriteLn('Not enough room!');
  383.  
  384.   ___________________________________________________________________________
  385.  
  386.   Method:       COUNT: WORD
  387.  
  388.   Type:         Function
  389.  
  390.   Definition:   The COUNT method returns the number of items in the list.
  391.                 If the list is empty then COUNT returns 0.
  392.  
  393.   Usage:        If pSw^.COUNT = 0 Then
  394.                     WriteLn('No Switches on the command line.');
  395.  
  396.   ___________________________________________________________________________
  397.  
  398.   Method:       DONE
  399.  
  400.   Type:         Destructor
  401.  
  402.   Definition:   DONE will reclaim memory used by the list and reset all
  403.                 entries to nil.
  404.  
  405.   Usage:        pEnviron^.DONE;       ... or ...
  406.  
  407.                 Dispose(pEnviron, DONE);
  408.  
  409.   ___________________________________________________________________________
  410.  
  411.   Method:       FIND( target: string ): STRING
  412.  
  413.   Type:         Function
  414.  
  415.   Definition:   FIND is used to locate a given item in the list.  If a match
  416.                 is found then FIND will return the matching item. If the
  417.                 target is shorter that the item compared, FIND will match
  418.                 partial string.  ie. to find "/P=<filename>" use:
  419.  
  420.   Usage:        Parameter_File := pSw^.FIND('/P=');
  421.  
  422.                 If length(Parameter_File) > 0
  423.                 Then Filename := copy(Parameter_File,4,255)
  424.                 Else Filename := '';
  425.   ___________________________________________________________________________
  426.  
  427.   Method:       (Argument).INIT( LegalChars: CharSet )
  428.  
  429.   Type:         Constructor
  430.  
  431.   Definition:   This instance of INIT is used to fill the ARGUMENT list
  432.                 with items from the command line.  LegalChars is a set
  433.                 of characters to be used as indicators of legal arguments.
  434.  
  435.                 CLPARSER defaults to [#32..#127] - ['/','-','+'].
  436.  
  437.                 WARNING!  Do not use this command in your program until
  438.                           you have used pArg^.ERASE first!  Since
  439.                           this command is automatically executed when your
  440.                           program starts, allocated memory would become
  441.                           trapped and unusable!
  442.  
  443.   Usage:        pArg := New( pArgument, Init(['0'..'9']) )
  444.                 { scan for numbers only }
  445.  
  446.   ___________________________________________________________________________
  447.  
  448.   Method:       (Environ).INIT
  449.  
  450.   Type:         Constructor
  451.  
  452.   Definition:   This instance of INIT fills the ENVIRON list with all
  453.                 environment variables that will fit.  This is not an
  454.                 automatic-execution object.  You MUST use this first
  455.                 before you can access the data structure.
  456.  
  457.   Usage:        pEnv := New( pEnviron, INIT );
  458.  
  459.   ___________________________________________________________________________
  460.  
  461.   Method:       (PFile).INIT( filename: string, Comment: CharSet )
  462.  
  463.   Type:         Constructor
  464.  
  465.   Definition:   This is one of the more interesting objects in this unit.
  466.                 If the file specified by filename is found, then it is
  467.                 parsed for items to be added to the list.  White space
  468.                 before and after the item is stipped.  Blank lines and
  469.                 comment lines are skipped.  Comment lines are defined
  470.                 by the set of characters specified by Comment.  Any line
  471.                 whose first non-white space (tab or space) character is
  472.                 in the Comment set of characters is skipped.
  473.  
  474.   Usage:        Example Parameter File:  PARM.DAT
  475.  
  476.                         ; Sample Parameter file
  477.  
  478.                         *************  User Data *************
  479.  
  480.                         John Smith                               {1}
  481.                         Level=10                                 {2}
  482.                         Password=Not Now, Dear!                  {3}
  483.  
  484.                         *************  System Data ***********
  485.  
  486.                         Size=100                                 {4}
  487.                         Time=1:00                                {5}
  488.                         Delay=1000                               {6}
  489.  
  490.                         ; end of parameter file
  491.  
  492.                 Program example:
  493.  
  494.                         pPF := New(pPFile, Init( 'PARM.DAT', [';','*'] );
  495.  
  496.                 The {} numbers represent the position numbers in the list
  497.                 after execution.  The list will contain only 6 items.  All
  498.                 other line have been skipped.
  499.  
  500.   ___________________________________________________________________________
  501.  
  502.   Method:       (pWild).INIT( filemask:string; attributes:word );
  503.  
  504.   Type:         Constructor
  505.  
  506.   Definition:   This method fills the WILD list with items (filenames) that
  507.                 that match the filename mask.  This can build a potentially
  508.                 gigantic list.  CLPARSER is limited only to the amount of
  509.                 heap memory available.
  510.  
  511.                 The attributes parameter is identical to the attributes
  512.                 provided by Turbo's DOS unit.
  513.  
  514.   Usage:        pW := New(pWild,INIT('*.DOC',ANYFILE-HIDDEN-VOLUMEID));
  515.  
  516.   ___________________________________________________________________________
  517.  
  518.   Method:       NEXT: STRING
  519.  
  520.   Type:         Function
  521.  
  522.   Definition:   NEXT returns the next item in the list.  If the last item
  523.                 has already been accessed, then NEXT returns an empty
  524.                 string.  Use RESET to set the internal index back to the
  525.                 beginning of the list.  Use PREV to return the previous
  526.                 item.
  527.  
  528.   Usage:        Next_Item := pW^.NEXT;
  529.  
  530.   ___________________________________________________________________________
  531.  
  532.   Method:       NEXTCARGO(var pCargo:Pointer; var CargoSize:LongInt): STRING
  533.  
  534.   Type:         Function
  535.  
  536.   Definition:   NEXTCARGO returns the next item in the list including the
  537.                 cargo information. If the last item has already been
  538.                 accessed, then NEXT returns an empty string.  Use RESET to
  539.                 set the internal index back to the beginning of the list.
  540.                 Use PREVCARGO to return the previous item.
  541.  
  542.   Usage:        Next_Item := pW^.NEXTCARGO( DataPtr, DataSize );
  543.  
  544.   ___________________________________________________________________________
  545.  
  546.   Method:       OVERFLOW: BOOLEAN
  547.  
  548.   Type:         Function
  549.  
  550.   Definition:   Returns TRUE if INIT found more items than would fit in
  551.                 memory or in the list.
  552.  
  553.   Usage:        If pW^.OVERFLOW
  554.                 Then WriteLn('Sorry, not enough space for all files!');
  555.  
  556.  
  557.   ___________________________________________________________________________
  558.  
  559.   Method:       POSITION: WORD
  560.  
  561.   Type:         Function
  562.  
  563.   Definition:   When used with Parse_Argument or Parse_Switch POSITION
  564.                 returns the position on the command line where the current
  565.                 item was found.
  566.  
  567.                 Otherwise POSITION returns whatever value the programmer
  568.                 placed there with the ADD method.
  569.  
  570.   Usage:        Current_Switch := pSw^.NEXT;
  571.                 If pSw^.POSITION < pArg^.POSITION
  572.                 Then WriteLn('Ambiguous use of ',Current_Switch);
  573.  
  574.   ___________________________________________________________________________
  575.  
  576.   Method:       PREV: STRING
  577.  
  578.   Type:         Function
  579.  
  580.   Definition:   PREV backs up one entry and returns that item in the list.
  581.                 If already at the beginning, then PREV returns an empty
  582.                 string.
  583.  
  584.   Usage:        Previous_Item := pEnv^.PREV;
  585.  
  586.   ___________________________________________________________________________
  587.  
  588.   Method:       PREVCARGO(var pCargo:Pointer; var CargoSize:LongInt): STRING
  589.  
  590.   Type:         Function
  591.  
  592.   Definition:   PREV backs up one entry and returns that item in the list
  593.                 including cargo. If already at the beginning, then PREV
  594.                 returns an empty string.
  595.  
  596.   Usage:        Previous_Item := pEnv^.PREV( DataPtr, DataSize );
  597.  
  598.   ___________________________________________________________________________
  599.  
  600.   Method:       RESET
  601.  
  602.   Type:         Procedure
  603.  
  604.   Definition:   RESET simply resets the data structure's current entry
  605.                 index pointer to the beginning of the list.
  606.  
  607.   Usage:        If pArg^.NEXT := '' then pArg^.RESET;
  608.  
  609.   ___________________________________________________________________________
  610.  
  611.  
  612.  
  613.   CHANGES IN VERSION 3.x_____________________________________________________
  614.  
  615.   Version 3.x represents a change in the data structure philosophy.  When
  616.   CLPARSER was orginally designed, I used it as an included unit that was
  617.   compiled specifically for each project.  The maximum number of command line
  618.   switches and arguments was known at compile time, so the unit would be
  619.   as small or large as required.  No virtual methods were used, which allows
  620.   the smart linker to do it's thing, and the pointer arrays were only as
  621.   large as required.
  622.  
  623.   The decision to release CLPARSER for others required some thinking.  It is
  624.   my opinion now that the version released was in-ordinately wasteful of
  625.   memory resources.  Each instantiation required another 1024 pointers and
  626.   1024 bytes, whether it used them or not.  I knew that, for myself, this
  627.   would be un-acceptable.
  628.  
  629.   So; in Version 3.x NO memory (beyond the object itself) is used until an
  630.   item is added to the list.  Also there are NO virtual methods.  These were
  631.   removed to allow the smart linker to smart link and to provide EARLY
  632.   binding of objects.  These are a little faster and definately safer to
  633.   use.  The side effect is in inheritance.  It is my opinion that CLPARSER
  634.   is not a particularly good choice as a general list object.  I take my
  635.   hat off to Turbo Power's Object Professional as a source of good, general
  636.   purpose, objects.  So, "no virtual methods" is prefered in this type of
  637.   object.
  638.  
  639.   If you have purchased the SOURCE LICENSE, then you can virtualize until
  640.   you are blue in the face, if you wish.
  641.  
  642.   Nothing else has been added.  Only natures pure ingredients were used.
  643.  
  644.  
  645.  
  646.   REGISTRATION_______________________________________________________________
  647.  
  648.  
  649.   There is no charge for using this unit unless you are profitting from
  650.   it's use or you want the source code.  Commercial users MUST register
  651.   irregardless of whether you sell software or not.
  652.  
  653.   This version of CLPARSER.TPU is currently available for Turbo Pascal 5.5
  654.   and Turbo Pascal v6.0.
  655.  
  656.   Since the unit is in object format, you can make use of the primary objects
  657.   in your own programs.  You are free use this unit as is or as a basis for
  658.   your own objects under the following restrictions:
  659.  
  660.       o  Using CLParser.TPU for any commercial purpose, you must register
  661.          for a single-site license fee of $12.00.
  662.  
  663.       o  To use CLParser.TPU in a Public Domain release you must register.
  664.          Registration is free, but handling is $5.00 if you want the
  665.          distribution disk.
  666.  
  667.       o  To use CLParser.TPU with your own personal programs, no registrat-
  668.          ion is required.
  669.  
  670.   To obtain the source code you must register for a source-code license of
  671.   $20.00.  This license covers all above mentioned licenses.
  672.  
  673.   When registering, please remember to include your name, company name,
  674.   address, city, state/province and postal code.  You must also provide
  675.   your signiture with a request for the source license.
  676.  
  677.     NOTE: Registration entitles you to a license for use.  The software
  678.           remains the intellectual property of the copyright holder.
  679.  
  680.   If you are paying for registration, send MONEY ORDERS ONLY, please.
  681.  
  682.                         Greg L. Truesdell
  683.                         36 Seaview Drive
  684.                         Port Moody, BC CANADA
  685.                                     V3H 1N7
  686.  
  687.                         Tel: (604) 939-1009
  688.                         CompuServe: 75360,1303
  689.  
  690.   ___________________________________________________________________________
  691.  
  692.   ___________________________________________________________________________
  693.  
  694.   CLParser v3.2 Registration Form                                    08/06/92
  695.   ___________________________________________________________________________
  696.  
  697.              Remit to:
  698.                         Greg L. Truesdell
  699.                         36 Seaview Drive
  700.                         Port Moody, BC CANADA
  701.                                     V3H 1N7
  702.  
  703.            ┌──────────────────────────────────────────────────────┐
  704.            │ Send MONEY ORDERS ONLY if ordering outside of Canada │
  705.            └──────────────────────────────────────────────────────┘
  706.  
  707.     Registration Level
  708.  
  709.         [ ] Commercial Site License                     12.00   _____________
  710.  
  711.         [ ] Public Domain Usage License                  5.00   _____________
  712.  
  713.         [ ] Source Code License                         20.00   _____________
  714.  
  715.                                         TOTAL                   _____________
  716.  
  717.  
  718.     Name    _____________________________________________________
  719.  
  720.     Company _____________________________________________________
  721.  
  722.     Address _____________________________________________________
  723.  
  724.     City    ________________________________________   State\Prov ___________
  725.  
  726.                                                   Zip\Postal Code ___________
  727.  
  728.     Telephone No. (    )    -
  729.  
  730.   ___________________________________________________________________________
  731.  
  732.                  Complete if ordering a SOURCE CODE LICENSE
  733.   ___________________________________________________________________________
  734.  
  735.  
  736.     With my signature I certify that I will not disclose or distribute
  737.     modified or un-modified copies of the source to CLPARSER, and that no
  738.     modified copies of CLPARSER.TPU will be distributed in any form without
  739.     express permission of the copyright holder.  CLPARSER is the intellectual
  740.     property of the copyright holder and, as such, is licensed for USE ONLY
  741.     and remains the property of the copyright holder.
  742.  
  743.  
  744.     Signature ______________________________________
  745.                  REQUIRED FOR SOURCE CODE LICENSE
  746.  
  747.   ___________________________________________________________________________
  748.  
  749.  
  750.  
  751.          ----------------end-of-author's-documentation---------------
  752.  
  753.                          Software Library Information:
  754.  
  755.                     This disk copy provided as a service of
  756.  
  757.                            Public (software) Library
  758.  
  759.          We are not the authors of this program, nor are we associated
  760.          with the author in any way other than as a distributor of the
  761.          program in accordance with the author's terms of distribution.
  762.  
  763.          Please direct shareware payments and specific questions about
  764.          this program to the author of the program, whose name appears
  765.          elsewhere in  this documentation. If you have trouble getting
  766.          in touch with the author,  we will do whatever we can to help
  767.          you with your questions. All programs have been tested and do
  768.          run.  To report problems,  please use the form that is in the
  769.          file PROBLEM.DOC on many of our disks or in other written for-
  770.          mat with screen printouts, if possible.  PsL cannot debug pro-
  771.          programs over the telephone, though we can answer questions.
  772.  
  773.          Disks in the PsL are updated  monthly,  so if you did not get
  774.          this disk directly from the PsL, you should be aware that the
  775.          files in this set may no longer be the current versions. Also,
  776.          if you got this disk from another vendor and are having prob-
  777.          lems,  be aware that  some files may have become corrupted or
  778.          lost by that vendor. Get a current, working disk from PsL.
  779.  
  780.          For a copy of the latest monthly software library newsletter
  781.          and a list of the 4,000+ disks in the library, call or write
  782.  
  783.                            Public (software) Library
  784.                                P.O.Box 35705 - F
  785.                             Houston, TX 77235-5705
  786.  
  787.                                 1-800-2424-PSL
  788.                              MC/Visa/AmEx/Discover
  789.  
  790.                           Outside of U.S. or in Texas
  791.                           or for general information,
  792.                               Call 1-713-524-6394
  793.  
  794.  
  795.